package com.xuecheng.content.service.jobHandler;

import com.xuecheng.base.exception.XueChengPlusException;
import com.xuecheng.content.feignclient.SearchServiceClient;
import com.xuecheng.content.mapper.CoursePublishMapper;
import com.xuecheng.content.model.dto.CourseIndex;
import com.xuecheng.content.model.po.CoursePublish;
import com.xuecheng.messagesdk.model.po.MqMessage;
import com.xuecheng.messagesdk.service.MessageProcessAbstract;
import com.xuecheng.messagesdk.service.MqMessageService;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class CoursePublishTask extends MessageProcessAbstract {

    @Autowired
    private CoursePublishMapper coursePublishMapper;

    @Autowired
    private SearchServiceClient searchServiceClient;

    /**
     * 课程发布任务处理（任务调度入口）
     */
    @XxlJob("CoursePublishJobHandler")
    public void coursePublishJobHandler() {
        // 获取分片索引
        int shardIndex = XxlJobHelper.getShardIndex();
        // 获取分片总数
        int shardTotal = XxlJobHelper.getShardTotal();
        // 打印日志
        log.debug("shardIndex=" + shardIndex + ",shardTotal=" + shardTotal);
        // 执行任务处理逻辑（参数：分片序号、分片总数、消息类型、一次最多取到的任务数、一次任务调度执行的超时时间）
        process(shardIndex, shardTotal, "course_publish", 30, 60);
    }

    /**
     * 执行任务内容
     *
     * @param mqMessage 消息记录
     * @return boolean true:处理成功
     */
    @Override
    public boolean execute(MqMessage mqMessage) {
        // 获取课程id
        Long courseId = Long.valueOf(mqMessage.getBusinessKey1());

        // 课程资源静态化（未实现，暂时用不到）
         generateCourseHtml(mqMessage, courseId);

        // 保存到ES
        saveCourseIndex(mqMessage, courseId);

        // 保存到Redis
        saveCourseCache(mqMessage, courseId);

        return true;
    }

    /*保存到Redis*/
    private void saveCourseCache(MqMessage mqMessage, Long courseId) {
        log.debug("开始进行课程资源Redis缓存处理,课程id:{}", courseId);
        // 获取任务id
        Long taskId = mqMessage.getId();
        // 消息处理的service
        MqMessageService mqMessageService = this.getMqMessageService();
        // 获取第三阶段（保存到Redis缓存）的处理状态
        int stageThree = mqMessageService.getStageThree(taskId);
        // 若状态为已完成
        if (stageThree == 1) {
            log.debug("课程资源保存到Redis缓存为已完成状态，课程id:{}", courseId);
            return;
        }
        // 未完成状态，保存到Redis缓存

        // 保存第三阶段状态
        mqMessageService.completedStageThree(taskId);
    }

    /*保存到ES*/
    private void saveCourseIndex(MqMessage mqMessage, Long courseId) {
        log.debug("开始进行课程资源ES处理,课程id:{}", courseId);
        // 获取任务id
        Long taskId = mqMessage.getId();
        // 消息处理的service
        MqMessageService mqMessageService = this.getMqMessageService();
        // 获取第二阶段（保存到ES）的处理状态
        int stageTwo = mqMessageService.getStageTwo(taskId);
        // 若状态为已完成
        if (stageTwo == 1) {
            log.debug("课程资源保存到ES为已完成状态，课程id:{}", courseId);
            return;
        }

        // 未完成状态
        // 根据课程id查询课程信息
        CoursePublish coursePublish = coursePublishMapper.selectById(courseId);
        // 创建课程索引对象
        CourseIndex courseIndex = new CourseIndex();
        // 对象拷贝
        BeanUtils.copyProperties(coursePublish, courseIndex);
        // Feign远程调用，保存到ES
        Boolean add = searchServiceClient.add(courseIndex);
        // 判断是否成功
        if (!add) XueChengPlusException.cast("课程发布信息保存到ES失败");

        // 保存第二阶段状态
        mqMessageService.completedStageTwo(taskId);
    }

    /*课程资源静态化*/
    private void generateCourseHtml(MqMessage mqMessage, Long courseId) {
        log.debug("开始进行课程资源静态化,课程id:{}", courseId);
        // 获取任务id
        Long taskId = mqMessage.getId();
        // 消息处理的service
        MqMessageService mqMessageService = this.getMqMessageService();
        // 获取第一阶段（课程资源静态化）的处理状态
        int stageOne = mqMessageService.getStageOne(taskId);
        // 若状态为已完成
        if (stageOne == 1) {
            log.debug("课程资源静态化为已完成状态，课程id:{}", courseId);
            return;
        }
        // 未完成状态，进行静态化处理

        // 保存第一阶段状态
        mqMessageService.completedStageOne(taskId);
    }
}
